class_name ActionContainer
extends Node2D

const DURATION_WEIGHT_CACHE := 200
const PLAYER_REFFAB = preload("res://scences/characters/player.tscn")
const SPARK_PREFAB = preload("res://scences/spark/spark.tscn")


@export var ball : Ball
@export var goal_home : Goal
@export var goal_away : Goal
#@export var team_home : String
#@export var team_away : String

@onready var kick_offs: Node2D = %KickOffs
@onready var spawns: Node2D = %Spawns

var is_checking_for_kickoff_readiness := false
var squad_home : Array[Player] = []
var squad_away : Array[Player] = []
var time_since_last_cache_refresh := Time.get_ticks_msec()

func _init() -> void:
	GameEvents.team_reset.connect(on_team_reset.bind())
	GameEvents.impact_received.connect(on_impact_received.bind())
	
func _ready() -> void:
	squad_home = spawns_players(GameManager.current_match.country_home,goal_home)
	goal_home.initialize(GameManager.current_match.country_home)
	spawns.scale.x = -1
	kick_offs.scale.x = -1
	squad_away = spawns_players(GameManager.current_match.country_away,goal_away)
	goal_away.initialize(GameManager.current_match.country_away) 
	setup_control_scheme()

func _process(delta: float) -> void:
	if Time.get_ticks_msec() - time_since_last_cache_refresh > DURATION_WEIGHT_CACHE:
		time_since_last_cache_refresh = Time.get_ticks_msec()
		set_on_duty_weight()
	
	if is_checking_for_kickoff_readiness:
		check_for_kickoff_readiness()

func spawns_players(country : String,own_goal :Goal)-> Array[Player]:
	var player_nodes : Array[Player] = []
	var players = DataLoader.get_squad(country)
	var target_goal := goal_home if own_goal == goal_away else goal_away
	for i in players.size():
		var player_position = spawns.get_child(i).global_position as Vector2
		var player_data := players[i] as PlayerResource
		var kickoff_position :Vector2 = player_position
		if i > 3:
			kickoff_position = kick_offs.get_child(i - 4).global_position as Vector2 
		var player := spawns_player(player_position,kickoff_position,own_goal,target_goal,player_data,country)
		player_nodes.append(player)
		add_child(player)
		
	return player_nodes
		
func spawns_player(player_position:Vector2 ,kickoff_position: ,own_goal:Goal,target_goal:Goal,player_data:PlayerResource,country:String) -> Node2D:
	var player : Player= PLAYER_REFFAB.instantiate()
	player.initialize(player_position,kickoff_position, ball, own_goal, target_goal, player_data,country)
	player.swap_request.connect(on_player_swap_request.bind())
	return player

func set_on_duty_weight() -> void:
	for squad in [squad_away,squad_home]:
		var cpu_player : Array[Player] = squad.filter(
			func(p: Player):
				return p.control_scheme == Player.ControlScheme.CPU and p.role != Player.Role.GOALIE
		) 
		
		cpu_player.sort_custom(func(p1:Player, p2:Player):
			return p1.spawn_position.distance_to(ball.position) < p2.spawn_position.distance_to(ball.position))
		
		for i in range(cpu_player.size()):
			cpu_player[i].weight_on_duty_steering = 1 - ease(float(i)/10.0,0.1)

func on_player_swap_request(requester: Player) -> void:
	var squad := squad_home if requester.country == squad_home[0].country else squad_away
	var cpu_player : Array[Player] = squad.filter(
		func(p: Player):
			return p.control_scheme == Player.ControlScheme.CPU and p.role != Player.Role.GOALIE
	) 
	cpu_player.sort_custom(func(p1:Player, p2:Player):
		return p1.position.distance_to(ball.position) < p2.position.distance_to(ball.position))
	
	var closet_cpu_to_ball : Player = cpu_player[0]
	
	if closet_cpu_to_ball.position.distance_squared_to(ball.position) < requester.position.distance_squared_to(ball.position):
		var player_control_scheme := requester.control_scheme
		requester.set_control_scheme(Player.ControlScheme.CPU)
		closet_cpu_to_ball.set_control_scheme(player_control_scheme)

func check_for_kickoff_readiness() -> void:
	for squad in [squad_home,squad_away]:
		for player : Player in squad:
			if not player.is_ready_for_kickoff():
				return
	setup_control_scheme()
	is_checking_for_kickoff_readiness = false
	GameEvents.kickoff_ready.emit()

func setup_control_scheme() -> void:
	setup_control_schemes()
	var p1_country := GameManager.player_setup[0]
	if GameManager.is_coop():
		var player_squad := squad_home if squad_home[0].country == p1_country else squad_away
		player_squad[4].set_control_scheme(Player.ControlScheme.P1)
		player_squad[5].set_control_scheme(Player.ControlScheme.P2)
	elif GameManager.is_single_player():
		var player_squad := squad_home if squad_home[0].country == p1_country else squad_away
		player_squad[5].set_control_scheme(Player.ControlScheme.P1)
	else:
		var p1_squad := squad_home if squad_home[0].country == p1_country else squad_away
		var p2_squad := squad_home if p1_squad == squad_away else squad_away
		p1_squad[5].set_control_scheme(Player.ControlScheme.P1)
		p2_squad[5].set_control_scheme(Player.ControlScheme.P2)
		
func on_team_reset() -> void:
	is_checking_for_kickoff_readiness = true
	
func setup_control_schemes() -> void:
	for squad in [squad_home,squad_away]:
		for player : Player in squad:
			player.set_control_scheme(Player.ControlScheme.CPU)

func on_impact_received(impact_position: Vector2, _is_hight_impact : bool) -> void:
	var spark := SPARK_PREFAB.instantiate()
	spark.position = impact_position
	add_child(spark)
